package com.tkm.advancedFunctions.eg

import java.io.File

interface Node {
    fun render(): String
}

class DOMNode(val name: String) : Node {

    val properties = mutableMapOf<String, String>()
    val children = mutableListOf<Node>()

    override fun render(): String {
        val tagProperties = properties.map { (k, v) -> "$k=\"$v\"" }.joinToString(" ")
        val tagStart = "<$name $tagProperties>"
        val tagEnd = "</$name>"
        val tagContent = children.joinToString("") { it.render() }
        return "$tagStart$tagContent$tagEnd"
    }

    operator fun String.invoke(block: DOMNode.() -> Unit): Node {
        val node = DOMNode(this)
        block(node)
        this@DOMNode.children += node
        return node
    }

    operator fun String.invoke(value: String) {
        this@DOMNode.properties[this] = value
    }

    operator fun String.unaryPlus() {
        val node = StringNode(this)
        this@DOMNode.children += node
    }
}

class StringNode(val content: String) : Node {
    override fun render(): String {
        return content
    }
}

fun html(block: DOMNode.() -> Unit): Node {
    val node = DOMNode("html")
    //  block(node)等同于node.block()，只要确保block的receiver为node即可
    block(node)
    return node
}

fun DOMNode.head(block: DOMNode.() -> Unit): Node {
    val node = DOMNode("head")
    block(node)
    this.children += node
    return node
}

fun DOMNode.body(block: DOMNode.() -> Unit): Node {
    val node = DOMNode("body")
    block(node)
    this.children += node
    return node
}

fun main() {
    val htmlContent = html {

        head {
            "meta" { "charset"("UTF-8") }
        }
        body {
            "div" {
                "style"(
                    """
                    width: 200px; 
                    height: 200px; 
                    line-height: 200px; 
                    background-color: #C9394A;
                    text-align: center
                    """.trimIndent()
                )
                "span" {
                    "style"(
                        """
                        color: white;
                        font-family: Microsoft YaHei
                        """.trimIndent()
                    )
                    +"Hello HTML DSL!!"
                }
            }
        }
    }.render()

    File("Kotlin.html").writeText(htmlContent)
}
